package com.ipan.poi.utils;

import java.io.IOException;
import java.io.InputStream;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 日期时间工具类；
 * 
 * @author iPan
 * @version 2013-05-29
 */
public final class PoiDateHelper extends org.apache.commons.lang.time.DateUtils {
	private static Map<String, DateFormat> DEFAULT_DATE_FORMAT_CONTEXT = new ConcurrentHashMap<String, DateFormat>();
	private static final String CONFIG_PATH = "./dateHelper.properties";
	private static final String MUTI_DATE_PATTERN = "^.*(\\d{4}.*){2,}.*$";
	
	// 初始化模糊匹配上下文
	static {
		// 注册默认匹配器
		registerDateFormat("yyyy-MM-dd HH:mm:ss");
		registerDateFormat("yyyy/MM/dd HH:mm:ss");
		registerDateFormat("yyyyMMdd HH:mm:ss");
		registerDateFormat("yyyy-MM-dd");
		registerDateFormat("yyyy/MM/dd");
		registerDateFormat("yyyyMMdd");
		
		InputStream fin = null;
		try {
			fin = PoiDateHelper.class.getResourceAsStream(CONFIG_PATH);
			if (fin != null) {
				Properties config = new Properties();
				config.load(fin);
				// 项目申报角色名称定义
				String formats = config.getProperty("default_date_format");
				if (formats != null && formats.length() > 0) {
					String[] fmts = formats.split(",");
					for (String fmt : fmts) {
						registerDateFormat(fmt);
					}
				}
			}
		} catch (IOException e) {
			throw new RuntimeException("DateHelper配置文件加载失败！", e);
		} finally {
			if (fin != null) {
				try {
					fin.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	/**
	 * 字符串转换为时间；
	 */
	public static Date getDate(String str, String parsePatterns) {
		Date date = null;
        try {
			date = parseDate(str, new String[]{parsePatterns});
		} catch (ParseException e) {
			throw new RuntimeException(e.getMessage(), e);
		}
        return date;
    }
	
	/**
	 * 字符串转换为时间；
	 */
	public static Date getDate(String str, String[] parsePatterns) {
		Date date = null;
        try {
			date = parseDate(str, parsePatterns);
		} catch (ParseException e) {
			throw new RuntimeException(e.getMessage(), e);
		}
        return date;
    }
	
	/**
	 * 模糊匹配多个时间格式；
	 * 注意：如果正则表达式捕获到是时间格式，那么对应的时间格式必须经过时间转换器注册！
	 * 例如：“^(\\d{4}\\.\\d{1,2})-(\\d{4}\\.\\d{1,2})$”格式的日期，必须注册过“yyyy.MM”转换器；
	 */
	public Date[] fuzzyMatchDate(String[] regex, String value) {
		Pattern pattern = null;
		Matcher matcher = null;
		Date[] result = null;
		for (String r : regex) {
			pattern = Pattern.compile(r);
			matcher = pattern.matcher(value);
			if (matcher.find()) {
				int count = matcher.groupCount();
				result = new Date[count];
				for (int i=0; i<count; ++i) {
					result[i] = fuzzyParseDate(matcher.group(i + 1));
				}
				break;
			}
		}
		return result;
	}
	
	/**
	 * 模糊匹配时间；
	 */
	public static Date fuzzyParseDate(String value) {
		Collection<DateFormat> formatList = DEFAULT_DATE_FORMAT_CONTEXT.values();
		if (formatList == null) {
			return null;
		}
		
		Date date = null;
		Iterator<DateFormat> iter = formatList.iterator();
		while (iter.hasNext()) {
			if (date != null) {
				break;
			}
			try {
				DateFormat format = iter.next();
				date = format.parse(value);
			} catch (ParseException e) {
				continue;
			}
		}
		return date;
	}
	
	/**
	 * 注册模糊匹配时间格式；
	 */
	public static void registerDateFormat(String pattern) {
		DateFormat format = null;
		if (!DEFAULT_DATE_FORMAT_CONTEXT.containsKey(pattern)) {
			format = new SimpleDateFormat(pattern);
			DEFAULT_DATE_FORMAT_CONTEXT.put(pattern, format);
		}
	}
	
	/**
	 * 注册模糊匹配时间格式；
	 */
	public static void registerAllDateFormat(Map<String, DateFormat> map) {
		DEFAULT_DATE_FORMAT_CONTEXT.putAll(map);
	}
	
	/**
	 * 是否存在多个日期格式；
	 * true 多个日期，false 单个日期；
	 */
	public static boolean isMutiDate(String strDate) {
		return Pattern.matches(MUTI_DATE_PATTERN, strDate);
	}
}
